home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / dpmigcc5.zip / RSX / SOURCE / SAMPLE / ALLOC.C next >
C/C++ Source or Header  |  1994-12-12  |  7KB  |  257 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. #define MAGIC (Header *)1111
  5.  
  6. typedef long Align;
  7. union header {
  8.     struct {
  9.         union header    *ptr;
  10.         unsigned        size;
  11.     } s;
  12.     Align x;
  13. };
  14. typedef union header Header;
  15.  
  16. static Header base;             /* Anfangs-Header */
  17. static Header *freep = NULL;    /* Einstiegspunkt in Free-Liste */
  18.  
  19. void* mymalloc(unsigned nbytes)
  20. {
  21.     Header *p, *prevp;
  22.     static Header *morecore(unsigned);
  23.     unsigned nunits;
  24.  
  25.     nunits = (nbytes+sizeof(Header)-1)/sizeof(Header) + 1;
  26.  
  27.     if ((prevp = freep) == NULL)           /* Erster Aufruf, Initialisierung */
  28.         {
  29.         base.s.ptr = freep = prevp = &base;
  30.         base.s.size = 0;
  31.         }
  32.     for (p = prevp->s.ptr; ; prevp = p, p = p->s.ptr)
  33.         {
  34.         if (p->s.size >= nunits)           /* Block gross genug */
  35.             {
  36.             if (p->s.size == nunits)       /* Block passt genau */
  37.                 prevp->s.ptr = p->s.ptr;
  38.             else
  39.                 {
  40.                 p->s.size -= nunits;       /* Block wird geteilt */
  41.                 p += p->s.size;            /*Pointer auf abgeschnittenes Ende*/
  42.                 p->s.size = nunits;
  43.                 }
  44.             freep = prevp;
  45.  
  46.             p->s.ptr=MAGIC;             /* da *ptr nur in free gebraucht wird,
  47.                                             Magic zur Ueberpruefung von free */
  48.  
  49.             return (void*) (p+1);       /* zeigt auf Speicherblock,nicht *H  */
  50.             }
  51.  
  52.         if ( p == freep)                /* p wieder beim Anfang,dh kein Platz*/
  53.             if ((p = morecore(nunits)) == NULL)
  54.                 return NULL;
  55.     }
  56. }
  57.  
  58. #define NALLOC  512    /* 512 * Header = 4 KB */
  59.  
  60. /* Eine static-Funktion ist ausserhalb ihres Files nicht sichtbar       */
  61.  
  62. static Header *morecore(unsigned nu)
  63. {
  64.     void *cp, *sbrk(int);
  65.     void myfree(void*);
  66.     Header *up;
  67.     if (nu < NALLOC)
  68.         nu = NALLOC;
  69.     cp = sbrk(nu * sizeof(Header));
  70.     if (cp == (char *) -1)              /* sbrk liefert -1 im Fehlerfall */
  71.         return NULL;
  72.     up = (Header*) cp;
  73.     up->s.size = nu;                    /* Groesse wird eingetragen     */
  74.     up->s.ptr = MAGIC;                  /* damit sich free nicht beschwert */
  75.     myfree((void*)(up+1));               /* Einbau in Free-Liste         */
  76.     return freep;
  77. }
  78.  
  79. void myfree(void *ap)                   /* Rueckgabe an Free-Liste      */
  80. {
  81.     Header *bp, *p;
  82.  
  83.     bp = (Header*) ap - 1;              /* Hier ist der Header des Blocks */
  84.  
  85.         /* Die Liste wird durchmustert, der Block soll der
  86.            Adressgroesse nach richtig eingefuegt werden,
  87.            um Defragmentierung zu ermoeglichen.                         */
  88.  
  89.     if (bp->s.ptr!=MAGIC) {
  90.         printf("bad magic number in pointer at %08lX %lu\n",ap,ap);
  91.         return ;
  92.         }
  93.     for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr)
  94.         if (p >= p->s.ptr && (bp > p || bp < p->s.ptr))
  95.             break;      /* bp liegt vor Block mit kleinster oder hinter
  96.                            Block mit groesster Adresse */
  97.  
  98.     if (bp + bp->s.size == p->s.ptr)
  99.         {                       /* Vereinigung mit oberem Nachbarn      */
  100.          bp->s.size += p->s.ptr->s.size;
  101.          bp->s.ptr = p->s.ptr->s.ptr;
  102.         }
  103.     else
  104.         bp->s.ptr = p->s.ptr;
  105.     if ( p + p->s.size == bp ) {
  106.                                 /* Vereinigung mit unterem Nachbarn     */
  107.         p->s.size += bp->s.size;
  108.         p->s.ptr = bp->s.ptr;
  109.     } else
  110.         p->s.ptr = bp;
  111.     freep = p;
  112. }
  113.  
  114. void* myrealloc(void *oldp,unsigned newsize)
  115. {
  116.   void *newp ;
  117.   Header *h ;
  118.   unsigned oldsize ;
  119.  
  120.   if (oldp==NULL)
  121.         return ( mymalloc(newsize) ) ;
  122.  
  123.   h = (Header *)oldp - 1 ;
  124.   if (h->s.ptr!=MAGIC) {
  125.         printf("bad magic number in pointer at %08lX %lu\n",oldp,oldp);
  126.         return (NULL);
  127.         }
  128.  
  129.   oldsize = h->s.size * sizeof(Header) - sizeof(Header) ;   /* size in bytes */
  130.   printf("Pointer oldsize=0x%08lX %lu\n",oldsize,oldsize);
  131.  
  132.   myfree(oldp);
  133.   newp = mymalloc(newsize);
  134.   if  (newp==NULL)
  135.         return NULL ;
  136.   if (newp!=oldp)
  137.         memcpy(newp,oldp,(newsize < oldsize) ? newsize : oldsize ) ;
  138.   return (newp) ;
  139. }
  140.  
  141. void* mycalloc(unsigned nelem,unsigned size)
  142. {
  143.   void *p = mymalloc(nelem*size) ;
  144.  
  145.   if (p) bzero(p,nelem*size) ;
  146.   return p ;
  147. }
  148.  
  149. printfree()
  150. {
  151.   Header *p ;
  152.  
  153.   for (p=&base ; ; p=p->s.ptr)
  154.         {
  155.         printf("base=%08lX size=%5d\n",(char *)p,p->s.size*sizeof(Header));
  156.         if (p->s.ptr==&base) break ;
  157.         }
  158. }
  159.  
  160. void bfree(void* p,unsigned int n)  /* p-> Block ; n=sizeof block */
  161. {
  162. Header *bfreeheader ;   /* header fuer block */
  163. unsigned int units ;
  164.  
  165. if ( freep == NULL)           /* Erster Aufruf, Initialisierung */
  166.         {
  167.         base.s.ptr = freep = &base;
  168.         base.s.size = 0;
  169.         }
  170.  
  171. units= (n-1)/sizeof(Header) + 1 ;
  172.  
  173. if (n % sizeof(Header) ) units-- ;      /* falls blocksize % 8 nicht 0
  174.                                         sollen die letzten Bytes nicht
  175.                                         verwendet werden */
  176. bfreeheader=(Header*)p;
  177.  
  178. bfreeheader->s.ptr  = MAGIC ;
  179. bfreeheader->s.size = units ;
  180.  
  181. myfree( (void *)(bfreeheader+1));
  182. }
  183.  
  184. static int a[1024];
  185. int* allocstatic()
  186. {
  187. if ( freep == NULL)           /* Erster Aufruf, Initialisierung */
  188.         {
  189.         base.s.ptr = freep = &base;
  190.         base.s.size = 0;
  191.         }
  192. return a;
  193. }
  194.  
  195.  
  196. int main()
  197. {
  198.     char c;
  199.     int bool ;
  200.     unsigned n,b;
  201.     void *p ;
  202.  
  203.     while (1){
  204.         bool=1;
  205.         printf("\n(m)alloc (c)alloc (f)ree (r)ealloc (s)tatic (b)free (q)uit : ");
  206.  
  207.         fflush(stdin);
  208.         scanf("%c",&c);
  209.         fflush(stdin);
  210.  
  211.         switch(c)
  212.         {
  213.         case 'm' : printf("Wieviel Bytes : ");
  214.                    scanf("%d",&n);
  215.                    p=mymalloc(n);
  216.                    printf("Pointer zeigt auf Adresse 0x%08lX %lu\n",p,p);
  217.                    break;
  218.  
  219.         case 'c' : printf("Wieviel Elemente und Groesse der Elem. : ");
  220.                    scanf("%d %d",&n,&b);
  221.                    p=mycalloc(n,b);
  222.                    printf("Pointer zeigt auf Adresse 0x%08lX %d\n",p,p);
  223.                    break;
  224.  
  225.         case 'f' : printf("Welche Addresse : ");
  226.                    scanf("%d",&n);
  227.                    p=(void *)n;
  228.                    myfree(p);
  229.                    break;
  230.  
  231.         case 'r' : printf("Welche Addresse und wieviel Bytes : ");
  232.                    scanf("%d %d",&n,&b);
  233.                    p=(void *)n;
  234.                    p=myrealloc(p,b);
  235.                    printf("Pointer zeigt auf Address 0x%08lX %lu\n",p,p);
  236.                    break;
  237.  
  238.         case 's' : p=(void *)allocstatic();
  239.                    printf("static Pointer zeigt auf 0x%08lX %lu\n",p,p);
  240.                    break;
  241.  
  242.         case 'b' : printf("Welche Addresse und wieviel Bytes : ");
  243.                    scanf("%d %d",&n,&b);
  244.                    p=(void *)n;
  245.                    bfree(p,b);
  246.                    break;
  247.         case 'q' :
  248.                     printf("exit prg\n");
  249.                     return(0) ;
  250.         default : bool=0;
  251.                   break;
  252.         }
  253.         if (bool)
  254.             printfree();
  255.     }
  256. }
  257.